/*
	File:		BitmapFont.cpp
	Course:		SGD 1301
	Author:		dmonroe
	Purpose:	CBitmapFont class will draw text on the screen
				using a font image
*/

#include "BitmapFont.h"

#include "../SGD Wrappers/CSGD_TextureManager.h"
#include <cassert>


////////////////////////////////////////////////////////////
// CONSTRUCTOR
CBitmapFont::CBitmapFont(void)
{
	m_nCellWidth	= 0;
	m_nCellHeight	= 0;
	m_nNumRows		= 0;
	m_nNumCols		= 0;
		
	m_nImageID		= -1;
	
	m_cFirstChar	= 0;
	m_bOnlyUpper	= false;
}


////////////////////////////////////////////////////////////
// DESTRUCTOR
CBitmapFont::~CBitmapFont(void)
{
}


////////////////////////////////////////////////////////////
// Initialize			- set up the font
//
// NOTE:
//		ALL images must have a size which is a power of 2 (512x256, etc)
//		The font MUST be in ASCII order
void CBitmapFont::Initialize( void )
{
	// Load the font image
	m_nImageID	= CSGD_TextureManager::GetInstance()->LoadTexture(
					_T("resource/graphics/PN_Font.png") );

	// Set the attributes
	m_nCellWidth	= 32;
	m_nCellHeight	= 32;
	m_nNumRows		= 6;
	m_nNumCols		= 10;

	m_cFirstChar	= _T(' ');	// space
	m_bOnlyUpper	= true;
}

////////////////////////////////////////////////////////////
// Shutdown			- unload the assets
void CBitmapFont::Shutdown( void )
{
	// Unload the font
	if( m_nImageID != -1 )
	{
		CSGD_TextureManager::GetInstance()->UnloadTexture( m_nImageID );
		m_nImageID = -1;
	}
}


////////////////////////////////////////////////////////////
// Draw				- convert the text to tile ids within the 
//					  font image & render to the screen
void CBitmapFont::Draw( const TCHAR* strOutput,
						int nX,		int nY,
						float fScale,	DWORD dwColor )
{
	// Validate the image
	assert( m_nImageID != -1 && "CBitmapFont::Draw - image is not valid" );
	assert( strOutput != nullptr && "CBitmapFont::Draw - text is null" );


	// Store the starting x value for newlines
	int nColStart = nX;

	// Iterate through each character in the string
	for( int i = 0; strOutput[ i ] != 0; i++ )
	{
		// Get the character we're on 
		TCHAR ch = strOutput[ i ];


		// Check for whitespace
		if( ch == _T('\n') )
		{
			nY += (int)(m_nCellHeight * fScale);
			nX =  nColStart;
			continue;
		}
		else if( ch == _T(' ') )
		{
			nX += (int)(m_nCellWidth * fScale);
			continue;
		}
		else if( ch == _T('\t') )
		{
			int diff = (int)((nX - nColStart) / (m_nCellWidth * fScale));
			int tab  = 4 - (diff % 4);

			nX += (int)(tab * m_nCellWidth * fScale);
			continue;
		}



		// Convert to uppercase?
		if( m_bOnlyUpper )
			ch = _totupper( ch );

		// Calculate the cell id of the character
		int id = ch - m_cFirstChar;

		RECT rTile = CellAlgorithm( id );

		// Draw the character
		CSGD_TextureManager::GetInstance()->Draw(
			m_nImageID, nX, nY, fScale, fScale,
			&rTile, 0.0f, 0.0f, 0.0f, dwColor );


		// Move to the next space on screen
		nX += (int)(m_nCellWidth * fScale);
	}
}


////////////////////////////////////////////////////////////
// CellAlgorithm			- convert a tile id to a source rect
RECT CBitmapFont::CellAlgorithm( int nTileID ) const
{
	// Validate the parameter
	assert( nTileID >= 0 && nTileID < m_nNumCols * m_nNumRows && "CBitmapFont::CellAlgorithm - invalid tile ID" );


	// Calculate the rectangle for the tile
	RECT rTile = { };

	rTile.left	= (nTileID % m_nNumCols) * m_nCellWidth;
	rTile.top	= (nTileID / m_nNumCols) * m_nCellHeight;

	rTile.right	= rTile.left + m_nCellWidth;
	rTile.bottom= rTile.top  + m_nCellHeight;


	return rTile;
}
